<?php
class ccdsModuleManager
{
    private $aClasses=array();

    private $ccdSQL;
    private $tools;
    private $BackendUserPlugins=array();
    private $events;

		private $userPlugins = array();

		//---------------------------------------------------------------------------------------------------------------------------
		// Function: __construct    
		//---------------------------------------------------------------------------------------------------------------------------
  
    private function __construct( )
    {
        $this->ccdSQL=ccdSQL::getInstance();
        $this->config=ccdsConfig::getInstance();
    }
		//---------------------------------------------------------------------------------------------------------------------------
		// Function: scan    
		//---------------------------------------------------------------------------------------------------------------------------
  
		public function scan() 
		{
			$plugin_folder = $this->config->get( 'DOC_ROOT' ) . $this->config->get( 'WEB_ROOT' ) . $this->config->get( 'CMS_ROOT' ). 'modules/';
			
			$dirHandle=opendir( $plugin_folder );
			$moduleArray=array();
			
			while ( false !== ( $dir=readdir( $dirHandle )) )
			{
			    if ('.' == $dir || '..' == $dir) continue;
			    if (is_dir($plugin_folder.$dir) && is_file($plugin_folder.$dir.'/'.$dir.'.inc.php')) {
			    	require($plugin_folder.$dir.'/'.$dir.'.inc.php');
			    } 
			}
			
			closedir ($dirHandle);      			

			$plugin_folder = $this->config->get( 'EXTENSION_DIR').'ccdsModules/';
			
			$moduleArray=array();
			
			$query = "SELECT DISTINCT module_name FROM modules WHERE module_active=1";
			$res = $this->ccdSQL->query($query);
			
			while ( $row = $this->ccdSQL->fetch_assoc($res) )
			{
					$dir = $row['module_name'];
			    if (is_dir($plugin_folder.$dir) && is_file($plugin_folder.$dir.'/'.$dir.'.inc.php')) {
			    	require($plugin_folder.$dir.'/'.$dir.'.inc.php');
			    	$this->userPlugins[] = $dir;
			    } 
			}
			
			foreach ($this->events as $event => $functions) {
				usort($functions,array($this,'sort'));
				$this->events[$event]=$functions;
			}
						
		}


		//---------------------------------------------------------------------------------------------------------------------------
		// Function: sort    
		//---------------------------------------------------------------------------------------------------------------------------
  		
		function sort($a,$b) {

		    if ($a[2] == $b[2]) {
		        return 0;
		    }
		    return ($a[2] < $b[2]) ? -1 : 1;
			
		}
		//---------------------------------------------------------------------------------------------------------------------------
		// Function: sort    
		//---------------------------------------------------------------------------------------------------------------------------

		function getUserPlugins() {
			
			return $this->userPlugins;
			
		}

		//---------------------------------------------------------------------------------------------------------------------------
		// Function: &getInstance    
		//---------------------------------------------------------------------------------------------------------------------------
  
    function &getInstance( )
    {
        static $obj;

        if ( !$obj )
        {
            $obj=new ccdsModuleManager();
        }
        return $obj;
    }

		//---------------------------------------------------------------------------------------------------------------------------
		// Function: register    
		//---------------------------------------------------------------------------------------------------------------------------
      
    function register($eventName,$className,$functionName,$priority=100) 
    {
    	if (!is_array($this->events[$eventName])) $this->events[$eventName]=array();
    	$this->events[$eventName][] = array($className,$functionName,$priority);
    	
    }

		//---------------------------------------------------------------------------------------------------------------------------
		// Function: unregister    
		//---------------------------------------------------------------------------------------------------------------------------
    
    function unregister($eventName,$className,$functionName) 
    {
    	if (!is_array($this->events[$eventName])) return false;
    	foreach ($this->events[$eventName] as $index => $values) 
    	{
    		if ($values[0] == $className && $values[1] == $functionName)
    		{
    			unset($this->events[$eventName][$index]);
    			return true;
    		}
    	}
    	return false;
    }

		//---------------------------------------------------------------------------------------------------------------------------
		// Function: call    
		//---------------------------------------------------------------------------------------------------------------------------
    function call() {
    	$args = &func_get_args();
    	if (0 == count($args)) trigger_error('ccdsModuleManager: can\'t call event without name',E_WARNING);
    	$event = array_shift($args);
    	if (!is_array($this->events[$event])) return;
    	foreach ($this->events[$event] as $module) {
    		list($className,$functionName) = $module;
    		$class = $this->get($className);
    		call_user_func_array(array($class,$functionName),$args);
    	}
    }
    
		//---------------------------------------------------------------------------------------------------------------------------
		// Function: getBackendUserPlugin    
		//---------------------------------------------------------------------------------------------------------------------------
    function getBackendUserPlugin( $class_id )
    {
        if ( isset( $this->BackendUserPlugins[$class_id] ) )
            return $this->BackendUserPlugins[$class_id];

        $query=
            "SELECT * FROM classes LEFT JOIN extensions ON (class_key_ext_id = ext_id) LEFT JOIN projects ON (ext_key_project_id=project_id) WHERE class_id="
            . $this->ccdSQL->real_escape_string( $class_id );
        $res=$this->ccdSQL->query( $query );
        $row=$this->ccdSQL->fetch_assoc( $res );

        $file=
            $this->config->get( 'EXTENSION_DIR' ) . $row['project_dir'] . "/" . $row['ext_dir'] . "/"
            . $row['class_dir'] . "/backend/" . $row['class_name'] . ".inc.php";

        if ( is_file( $file ) )
        {
            $this->BackendUserPlugins[$class_id]=array
                (
                "file" => $file,
                "class_name" => $row['class_name']
                );

            return $this->BackendUserPlugins[$class_id];
        }
        $this->BackendUserPlugins[$class_id]=false;
        return false;
    }


		//---------------------------------------------------------------------------------------------------------------------------
		// Function: get    
		//---------------------------------------------------------------------------------------------------------------------------

    function get( $sClass )
    {
        if ( in_array( $sClass, $this->aClasses ) )
            return $aClasses[$sClass];
        $config=ccdsConfig::getInstance();

        if ( class_exists($sClass ) )
        {
            $aClasses[$sClass]=new $sClass;
        }
        elseif ( is_numeric( $sClass ) )
        {

            $query=
                "SELECT * FROM classes LEFT JOIN extensions ON (class_key_ext_id = ext_id) LEFT JOIN projects ON (ext_key_project_id=project_id) WHERE class_id="
                . $this->ccdSQL->real_escape_string( $sClass )." LIMIT 1 ";
            $res=$this->ccdSQL->query( $query );
            $row=$this->ccdSQL->fetch_assoc( $res );
            $ext_path=
                $this->config->get( 'EXTENSION_DIR' ) . $row['project_dir'] . "/" . $row['ext_dir'] . "/"
                . $row['class_dir'] . "/backend/";
            $file=$ext_path . $row['class_name'] . ".inc.php";

            if ( is_file( $file ) )
            {
							require_once( $file );
							$class_name='ccds'.$row['class_name'];
							$aClasses[$class_name]=new $class_name( $sClass, $ext_path );
							return $aClasses[$class_name];
						} else {
							trigger_error("class not found");
							return false;
						}
        }
        else
        {
            return false;
        }
        return $aClasses[$sClass];
    }
		//---------------------------------------------------------------------------------------------------------------------------


		//---------------------------------------------------------------------------------------------------------------------------
		// Function: getModuleConfiguration
		//---------------------------------------------------------------------------------------------------------------------------
		function getModuleConfiguration($module,$key,$project_id) {
			$query = "SELECT * FROM modules_configuration WHERE module_config_name='".$module."' AND module_config_key='".$key."' AND module_config_key_project_id='".$project_id."'";
			$res = $this->ccdSQL->query($query);
			if ($row = $this->ccdSQL->fetch_assoc($res))
			{
				$values = unserialize($row['module_config_value']);
				return $values;
			}
			return false;
		}


		//---------------------------------------------------------------------------------------------------------------------------
		// Function: setModuleConfiguration
		//---------------------------------------------------------------------------------------------------------------------------
		function setModuleConfiguration($module,$key,$project_id,$values) {
			$query = "DELETE FROM modules_configuration WHERE module_config_name='".$module."' AND module_config_key='".$key."' AND module_config_key_project_id='".$project_id."'";
			$res = $this->ccdSQL->query($query);
			$query = "INSERT INTO modules_configuration VALUES(
				'".$module."',
				'".$key."',
				'".$this->ccdSQL->real_escape_string(serialize($values))."',
				'".$project_id."'
			)";
			$res = $this->ccdSQL->query($query);
			return true;
		}
}
